package com.example.business.controller;


import com.example.api.client.OrderClient;
import com.example.api.client.StorageClient;
import io.seata.spring.annotation.GlobalTransactional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;


@RestController
public class HomeController {

    private static final Logger LOGGER = LoggerFactory.getLogger(HomeController.class);

    private static final String SUCCESS = "SUCCESS";
    private static final String FAIL = "FAIL";
    private static final String USER_ID = "U100001";
    private static final String COMMODITY_CODE = "C00321";
    private static final int ORDER_COUNT = 2;

    private final RestTemplate restTemplate;
    private final OrderClient orderClient;
    private final StorageClient storageClient;

    public HomeController(RestTemplate restTemplate, OrderClient orderClient,
                          StorageClient storageClient) {
        this.restTemplate = restTemplate;
        this.orderClient = orderClient;
        this.storageClient = storageClient;
    }

    @GetMapping("/")
    public String home() {
        return SUCCESS;
    }

    @GlobalTransactional(timeoutMills = 300000, name = "spring-cloud-demo-tx")
    @GetMapping(value = "/seata/rest", produces = "application/json")
    public String rest() {
        String result = restTemplate.getForObject(
                "http://storage/storage/" + COMMODITY_CODE + "/" + ORDER_COUNT,
                String.class);

        if (!SUCCESS.equals(result)) {
            throw new RuntimeException();
        }

        String url = "http://order/order";
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
        map.add("userId", USER_ID);
        map.add("commodityCode", COMMODITY_CODE);
        map.add("orderCount", ORDER_COUNT + "");

        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(
                map, headers);

        ResponseEntity<String> response = restTemplate.postForEntity(url, request,
                String.class);

        result = response.getBody();

        if (!SUCCESS.equals(result)) {
            throw new RuntimeException();
        }

        return SUCCESS;
    }

    @GlobalTransactional(timeoutMills = 300000, name = "spring-cloud-demo-tx")
    @GetMapping(value = "/seata/feign", produces = "application/json")
    public String feign() {
        String result = storageClient.deduct(COMMODITY_CODE, ORDER_COUNT);
        if (!SUCCESS.equals(result)) {
            throw new RuntimeException();
        }

        result = orderClient.create(USER_ID, COMMODITY_CODE, ORDER_COUNT);
        if (!SUCCESS.equals(result)) {
            throw new RuntimeException();
        }

        return SUCCESS;
    }
}
